---
title: "Cloudflare R2 Storage"
description: Store your Hot Updater bundles in Cloudflare R2 using the Wrangler CLI.
icon: cloudflare
---

## Installation

```package-install
npm install @hot-updater/cloudflare --save-dev
```

<Callout title="Recommended Approach">
For full R2 feature support including presigned URLs and better performance, use the S3-compatible AWS plugin. See the [AWS S3 Storage documentation](/docs/storage-plugins/aws) for more details.

Install the AWS plugin:

```package-install
npm install @hot-updater/aws --save-dev
```

Configure with R2:

```typescript
import { s3Storage } from '@hot-updater/aws';
import { defineConfig } from 'hot-updater';

export default defineConfig({
  storage: s3Storage({
    region: 'auto',
    endpoint: 'https://your-account-id.r2.cloudflarestorage.com',
    credentials: {
      accessKeyId: 'your-r2-access-key-id',
      secretAccessKey: 'your-r2-secret-access-key'
    },
    bucketName: 'my-r2-bucket'
  }),
  // ... other config
});
```

This approach provides full R2 compatibility with better performance and all S3 features.
</Callout>

## Setup

The easiest way to set up your backend is using the init command:

```package-install
npx hot-updater init
```

This interactive command will guide you through the setup process. For details on what the init command does, see the [Cloudflare](/docs/managed/cloudflare) documentation.

For manual configuration, use the settings below.

## Configuration

```typescript
interface R2StorageConfig {
  cloudflareApiToken: string;  // Cloudflare API token
  accountId: string;           // Cloudflare account ID
  bucketName: string;          // R2 bucket name
  basePath?: string;           // Optional base path within bucket
}
```

## Usage

```typescript
import { r2Storage } from '@hot-updater/cloudflare';
import { defineConfig } from 'hot-updater';

export default defineConfig({
  storage: r2Storage({
    accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
    cloudflareApiToken: process.env.CLOUDFLARE_API_TOKEN,
    bucketName: 'my-r2-bucket'
  }),
  // ... other config
});
```

## Limitations

- Does not support getDownloadUrl() - bundles cannot be downloaded via presigned URLs
- Uses CLI instead of SDK (slower performance)
- Limited compared to S3-compatible approach

## Protocol

`r2://`

This prefix is stored in the `storageUri` field in the database.
